package com.lujieni.springbooteasyexcel.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.github.pagehelper.PageHelper;
import com.lujieni.springbooteasyexcel.dao.OrderInfoBakDao;
import com.lujieni.springbooteasyexcel.dao.OrderInfoDao;
import com.lujieni.springbooteasyexcel.dto.OrderInfoDTO;
import com.lujieni.springbooteasyexcel.dto.StudentExportDTO;
import com.lujieni.springbooteasyexcel.listener.OrderInfoBakListener;
import com.lujieni.springbooteasyexcel.po.OrderInfoBakPO;
import com.lujieni.springbooteasyexcel.po.OrderInfoPO;
import com.lujieni.springbooteasyexcel.server.WebSocketServer;
import com.lujieni.springbooteasyexcel.service.SendMsgService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletResponse;
import javax.websocket.Session;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author：小鹿爱吃鱼
 * @Date: 2025/4/3 16:51
 * @Description:
 */
@RestController
@RequiredArgsConstructor
public class OrderInfoController {

    private static final Logger log = LoggerFactory.getLogger(OrderInfoController.class);
    private final OrderInfoDao orderInfoDao;
    private final OrderInfoBakDao orderInfoBakDao;
    private final SendMsgService sendMsgService;

    //数据导出接口 错误的方式
    @GetMapping("/badExportBiG")
    public void doExport(HttpServletResponse response) throws IOException, IOException {
        //从数据库获取数据
        List<OrderInfoDTO> data = new ArrayList<>();

        Example example = new Example(OrderInfoPO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThanOrEqualTo("period", 202001);


        orderInfoDao.selectByExample(example).forEach(e->{
            OrderInfoDTO target = new OrderInfoDTO();
            BeanUtils.copyProperties(e,target);
            data.add(target);
        });
        //设置响应头
        response.setHeader("Content-Disposition", "attchment;filename=" + URLEncoder.encode("账期列表.xlsx", "UTF-8"));
        // 设置文本内省
        response.setContentType("application/vnd.ms-excel");
        // 设置字符编码
        response.setCharacterEncoding("utf-8");
        //将数据写入Excel
        EasyExcel.write(response.getOutputStream(), OrderInfoDTO.class)
                .sheet("账期列表")
                .doWrite(data);
    }

    //数据导出接口 正确的方式
    @GetMapping("/goodExportBiG")
    public void doGoodExport(HttpServletResponse response, String userCode) throws IOException, IOException {
        //从数据库获取数据
        List<OrderInfoDTO> data = new ArrayList<>();

        Example example = new Example(OrderInfoPO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThanOrEqualTo("period", 202001);

        int total = orderInfoDao.selectCountByExample(example);
        if(total == 0){
            return;
        }else{
            //设置响应头
            response.setHeader("Content-Disposition", "attchment;filename=" + URLEncoder.encode("账期列表.xlsx", "UTF-8"));
            // 设置文本内省
            response.setContentType("application/vnd.ms-excel");
            // 设置字符编码
            response.setCharacterEncoding("utf-8");
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), OrderInfoDTO.class).build(); // 整个excel对象
            WriteSheet writeSheet = EasyExcel.writerSheet("账期列表").build(); // 每个sheet
            int pageSize = 5000; //每页5000条
            int pageTotal = total % pageSize == 0 ? total / pageSize: total / pageSize+1; //总共多少页
            BigDecimal perProgess = new BigDecimal("100").divide(new BigDecimal(String.valueOf(pageTotal)), 2, BigDecimal.ROUND_HALF_UP);
            boolean isFinish = false;
            for (int i = 1; i <= pageTotal ; i++) {
                List<Long> ids = orderInfoDao.getIdByPeroid(202001, (i-1)*pageSize, pageSize);
                example.clear();
                example.createCriteria().andIn("id", ids);
                orderInfoDao.selectByExample(example).forEach(e->{
                    OrderInfoDTO target = new OrderInfoDTO();
                    BeanUtils.copyProperties(e,target);
                    data.add(target);
                });
                excelWriter.write(data, writeSheet);
                data.clear();
                isFinish = showProgress(userCode, perProgess, i, isFinish);
            }
            excelWriter.finish();
        }
    }

    private boolean showProgress(String userCode, BigDecimal perProgess, int i, boolean isFinish) {
        BigDecimal nowProcess = perProgess.multiply(new BigDecimal(String.valueOf(i)));
        if(nowProcess.compareTo(new BigDecimal("100")) > 0){
            nowProcess = new BigDecimal("100");
            if(!isFinish){
                sendMsgService.sendMessageToSpecificClient("当前进度:"+nowProcess, userCode);
                isFinish = true;
            }
        }else{
            sendMsgService.sendMessageToSpecificClient("当前进度:"+nowProcess, userCode);
        }
        return isFinish;
    }


    @PostMapping("/import")
    @Transactional
    public void importCustomerDaily(@RequestParam MultipartFile file) throws IOException, InterruptedException {
        InputStream inputStream = file.getInputStream();
        EasyExcel.read(inputStream)
                .head(OrderInfoDTO.class)
                .registerReadListener(new OrderInfoBakListener(orderInfoBakDao))
                // 设置sheet,默认读取第一个
                .sheet()
                // 设置标题所在行数
                .headRowNumber(1)
                .doRead();
    }

}
